package com.gitee.apanlh.util.net.http.handler.body;

import com.gitee.apanlh.exp.HttpBodyParseException;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.encode.StrEncodeUtils;
import com.gitee.apanlh.util.net.http.HttpBody;
import com.gitee.apanlh.util.net.http.HttpClient;
import com.gitee.apanlh.util.net.http.HttpRequest;
import com.gitee.apanlh.util.reflection.ClassConvertUtils;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 	HTTPBody请求体/响应体解析
 * 	<br>根据实现HttpBodyParseStrategy接口来定义解析类型
 * 	
 * 	@author Pan
 */
public interface HttpBodyParseStrategy {
	
	/** 参数标记 */
	String KEY_PARAM 		= "?";
	String KEYS_PARAM 		= "&";
	String VALUE_PARAM	 	= "=";
			
	/**	
     * 	转化请求方式为NameValuePair格式(值对节点类型)
     * 	
     * 	@author Pan
	 *  @param  <V>     			值类型
     * 	@param 	paramMap			请求参数
     * 	@param 	hasParamUrlEncode	是否开启参数url
     * 	@return	String
     */
	default <V> String toNameValuePair(Map<String, V> paramMap, boolean hasParamUrlEncode) {
		if (MapUtils.isEmpty(paramMap)) {
			return null;
		}
		
		StringBuilder queryParamBuilder = new StringBuilder(256);
		int index = 0;
		
		Iterator<Entry<String, V>> iterator = IteratorUtils.entrySet(paramMap);
		while (iterator.hasNext()) {
			Entry<String, V> entry = iterator.next();
			String key = entry.getKey();
			V value = entry.getValue();
			
			if (index != 0) {
				queryParamBuilder.append(KEYS_PARAM);
			}

			if (hasParamUrlEncode) {
				queryParamBuilder.append(StrEncodeUtils.urlEncode(key)).append(VALUE_PARAM).append(StrEncodeUtils.urlEncode(String.valueOf(value)));
			} else {
				queryParamBuilder.append(key).append(VALUE_PARAM).append(value);
			}
			index++;
		}
  		return queryParamBuilder.toString();
	}

	/**
	 * 	将Bean转换成Map形式
	 * 	<br>LinkedHashMap
	 *
	 * 	@author Pan
	 * 	@param 	httpBody	请求体对象
	 * 	@return	Map
	 */
	default Map<String, ?> beanToLinkedMap(HttpBody httpBody) {
		Object requestBody = httpBody.getRequestBody();

		if (httpBody.isRequestBodyMap()) {
			return ClassConvertUtils.castMap(requestBody);
		}
		return ClassConvertUtils.toLinkedHashMap(requestBody);
	}

	/**
	 * 	解析接口
	 * 	
	 * 	@author Pan
	 * 	@param 	httpRequest	请求对象
	 * 	@param 	httpClient	HTTP客户端
	 * 	@return	HttpRequest
	 * 	@throws HttpBodyParseException	如果body解析失败则抛出此异常
	 */
	HttpRequest parse(HttpRequest httpRequest, HttpClient httpClient) throws HttpBodyParseException;
}
